package com.qzxy.premiumhotelsystem.task;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import com.qzxy.premiumhotelsystem.common.constant.RedisKeyConstant;
import com.qzxy.premiumhotelsystem.common.constant.VipOrderStatusConstant;
import com.qzxy.premiumhotelsystem.common.constant.VipStatusConstant;
import com.qzxy.premiumhotelsystem.domain.entity.Vip;
import com.qzxy.premiumhotelsystem.domain.entity.VipOrders;
import com.qzxy.premiumhotelsystem.domain.pojo.Mail;
import com.qzxy.premiumhotelsystem.domain.vo.VipEmailVO;
import com.qzxy.premiumhotelsystem.mapper.VipMapper;
import com.qzxy.premiumhotelsystem.mapper.VipOrdersMapper;
import com.qzxy.premiumhotelsystem.service.MailService;
import com.qzxy.premiumhotelsystem.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import jakarta.annotation.Resource;
import java.util.Date;
import java.util.List;


@Component
@Slf4j
public class VipAboutTask {

    @Resource
    private VipOrdersMapper vipOrdersMapper;
    @Resource
    private VipMapper vipMapper;
    @Resource
    private RedisUtil redisUtil;

    @Resource
    private MailService mailService;

    @Value("${spring.mail.username}")
    private String sendMailer;


    /**
     * 处理超时订单
     */
    @Scheduled(cron = "0 * * * * ?")  // 每分钟触发一次
    public void checkAndCancelUnpaidOrders() {
        log.info("处理vip超时订单");
        // 获取当前时间，减去 15 分钟
        Date fifteenMinutesAgo = DateUtil.offsetMinute(new Date(), -15);

        // 查找超过15分钟未支付的订单
        List<VipOrders> unpaidOrders = vipOrdersMapper.findUnpaidOrders(fifteenMinutesAgo);

        for (VipOrders vipOrders : unpaidOrders) {
            // 更新订单状态为已取消
            vipOrders.setStatus(VipOrderStatusConstant.VIP_ORDER_CANCELLED);
            vipOrdersMapper.updateById(vipOrders);
        }
    }

    /**
     * 修改vip已过期,也意味其实用户可享折扣都会延长到当天12点
     */
    @Scheduled(cron = "0 0 0 * * ?")  // 每天凌晨0点自动触发
    public void checkAndExpireVipStatus() {
        log.info("处理vip已过期状态");
        // 获取当前时间
        Date now = new Date();

        // 查询所有未过期的会员
        List<Vip> activeVips = vipMapper.findActiveVips();

        for (Vip vip : activeVips) {
            // 检查 end_time 是否早于当前时间
            if (vip.getEndTime().before(now)) {
                // 更新会员状态为已过期
                vip.setStatus(VipStatusConstant.VIP_EXPIRED);
                int updated = vipMapper.updateById(vip);
                if (updated != 0){
                    String cacheKey = RedisKeyConstant.VIP_KEY + vip.getGuestId();
                    redisUtil.deleteObject(cacheKey);
                }
            }
        }
    }

    /**
     * 失效超过一个月自动删除vip记录
     */
    @Scheduled(cron = "0 0 1 * * ?")  // 每天凌晨3点触发
    public void removeExpiredVips() {
        // 获取当前时间并减去一个月
        Date oneMonthAgo = DateUtil.offsetMonth(new Date(), -1);

        List<Vip> list = vipMapper.selectExpiredVips(oneMonthAgo);
        if (CollUtil.isEmpty(list)){
            return;
        }
        // 删除 status 为 "失效" 且 end_time 早于 oneMonthAgo 的记录
        Integer deleted = vipMapper.deleteExpiredVips(oneMonthAgo);

        //缓存有变动，批量删除缓存，下次重新读取
        for (Vip vip : list) {
            String cacheKey = RedisKeyConstant.VIP_KEY + vip.getGuestId();
            redisUtil.deleteObject(cacheKey);
        }
    }


    /**
     * vip临期3天提醒
     */
    @Scheduled(cron = "0 0 6 * * ?")  // 每天早上6点检查并发送通知
    public void notifyVipExpiry() {
        log.info("检查即将到期的VIP会员并发送通知");
        List<VipEmailVO> vipList = vipMapper.findVipsExpiringSoon();

        for (VipEmailVO vip : vipList) {
            String message = String.format("尊敬的用户，您的%sVIP会员将于%s到期，若您觉得本酒店的服务招待好，请及时续费，以享折扣。",
                    vip.getVipType(), DateUtil.formatDate(vip.getEndTime()));
            Mail mail = new Mail();
            mail.setText(message);
            mail.setFrom(sendMailer);
            mail.setSubject("臻品酒店vip即将到期提醒");
            mail.setSendTo(vip.getEmail());
            mailService.sendSimpleMail(mail);
            log.info("发送成功");
        }
    }



}
